package server;

import java.math.BigInteger;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.MessageDigest;
import java.util.Calendar;
import java.util.GregorianCalendar;

import model.Account;
import model.User;
import model.dao.AccountDAO;
import model.dao.UserDAO;

public class Server {

	private int day;
	private int month;
	private int year;
	private int hour;
	private int minute;
	private int second;

	private AccountDAO accountDAO;
	private UserDAO userDAO; 

	public void getDateTime() {
		GregorianCalendar g = new GregorianCalendar();
		day = g.get(Calendar.DATE);
		month = g.get(Calendar.MONTH) + 1;
		year = g.get(Calendar.YEAR);
		hour = g.get(Calendar.HOUR);
		minute = g.get(Calendar.MINUTE);
		second = g.get(Calendar.SECOND);
	}

	public Account getAccount(String username, int pin) {
		return accountDAO.getAccount(username, pin);
	}

	public Account getAccount(String username){
		return accountDAO.getAccount(username);
	}
	public User getUser(String accountName){
		return userDAO.getUser(accountName);
	}
	
	public void updateAccount(Account account) {
		accountDAO.updateAccount(account);
	}

	public Server(int port) {
		accountDAO = new AccountDAO();
		userDAO = new UserDAO();
		listen(port);
	}

	public void listen(int port) {
		try {
			ServerSocket server = new ServerSocket(port);

			boolean connected = true;
			while (connected) {
				Socket client = server.accept();
				new ServerProc(this, client).start();
			}
			server.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String oneTimePass(Account account, int token) {
		String out = md5(account.getUsername() + account.getPin());
		String tokenTxt = md5(account.getPassword() + token);
		tokenTxt = md5(tokenTxt + day + month + year + hour + minute + second);
		out = md5(out + tokenTxt);
		return out;
	}

	public boolean checkOneTimePass(String username, String tokenPass) {
		try {
			Account account = accountDAO.getAccount(username);
			if (account == null) {
				return false;
			}
			String out = md5(account.getUsername() + account.getPin());
			String tokenTxt = md5(tokenPass + day + month + year + hour
					+ minute + second);
			out = md5(out + tokenTxt);

			return account.getOneTimePassword().equals(out);
		} catch (Exception e) {
//			e.printStackTrace();
		}
		return false;
	}

	public String md5(String text) {
		String checksum = null;
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] buffer = text.getBytes();
			md.update(buffer);
			byte[] hash = md.digest();
			checksum = String.format("%032x", new BigInteger(1, hash));
		} catch (Exception ex) {
			System.out.println(ex);
		}

		return checksum;
	}

	public int getDay() {
		return day;
	}

	public int getMonth() {
		return month;
	}

	public int getYear() {
		return year;
	}

	public int getHour() {
		return hour;
	}

	public int getMinute() {
		return minute;
	}

	public int getSecond() {
		return second;
	}

	public static void main(String[] args) {
		new Server(7764);
	}
}
